package zjl.xest;

import zjl.graph.Edge;
import zjl.graph.Graph;
import zjl.graph.Path;
import zjl.graph.Vertex;
import zjl.graph.BaseEdge;
import zjl.graph.BaseVertex;
import zjl.graph.DijkstraShortestPathAlgorithm;
import zjl.graph.YenTopKShortestPathsAlgorithm;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;

public class TestGraph extends Graph{
    public TestGraph() { }

    public TestGraph(final String filename) {
        importFromFile(filename);
    }

    public void importFromFile(final String filename) {
        clear();

        try {
            // 1. read the file and put the content in the buffer
            FileReader input = new FileReader(filename);
            BufferedReader bufferedReader = new BufferedReader(input);

            boolean isFirstLine = true;
            String line;

            // 2. Read first line
            line = bufferedReader.readLine();
            while (line != null) {
                // 2.1 skip the empty line
                if (line.trim().equals("")) {
                    line = bufferedReader.readLine();
                    continue;
                }

                // 2.2 generate nodes and edges for the graph
                if (isFirstLine) {
                    // 2.2.1 obtain the number of nodes in the graph
                    isFirstLine = false;
                    int vertexNumt = Integer.parseInt(line.trim());
                    for (int i = 0; i < vertexNumt; i++) {
                        BaseVertex vertex = new Vertex();
                        this.addVertexInternal(vertex);
                    }
                } else {
                    // 2.2.2 find a new edge and put it in the graph
                    String[] strList = line.trim().split("\\s");

                    int startVertexId = Integer.parseInt(strList[0]);
                    int endVertexId = Integer.parseInt(strList[1]);
                    double weight = Double.parseDouble(strList[2]);

                    BaseEdge edge = new Edge(this.getVertexById(startVertexId), this.getVertexById(endVertexId), weight);
                    this.addEdgeInternal(edge);
                }

                line = bufferedReader.readLine();
            }

            bufferedReader.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void exportToFile(String filename) {
        // 1. prepare the text to export
        StringBuffer sb = new StringBuffer();
        sb.append(vertexNum + "\n\n");

        // ...
    }

    public static void main(String[] args) {
        Graph graph = new TestGraph("data/zjl/ksptest.dat");

        System.out.println("Graph Vertex Size = " + graph.getVertexNum());
        System.out.println("Graph Edge Size = " + graph.getEdgeNum());

        DijkstraShortestPathAlgorithm dspa = new DijkstraShortestPathAlgorithm(graph);
        Path path = dspa.getShortestPath(graph.getVertexById(0), graph.getVertexById(2));
        System.out.println("\nDijkstra Path[0->2] = " + path);

        YenTopKShortestPathsAlgorithm ytspa = new YenTopKShortestPathsAlgorithm(graph);
        List<Path> pathList = ytspa.getShortestPaths(graph.getVertexById(0), graph.getVertexById(3), 100);

        System.out.println("\nK-Shortest Paths Information = {");
        for (Path p : pathList) {
            System.out.println("\t" + p);
        }
        System.out.println("}");

        List<Path> pathList2 = ytspa.getShortestPaths(graph.getVertexById(0), graph.getVertexById(3), 100);

        System.out.println("\nK-Shortest Paths Information = {");
        for (Path p : pathList2) {
            System.out.println("\t" + p);
        }
        System.out.println("}");
    }
}
